package com.qys.livesMall.security.filter;

import com.qys.livesMall.cache.words.annotation.CheckWord;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.io.IOException;
import java.util.List;

/**
 * @menu BodyFilter
 * @date 2023/06/14 15:26
 */
//@Order(value = Ordered.HIGHEST_PRECEDENCE)
@Order(value = -1)
@Component
@WebFilter(urlPatterns = "/*")
public class BodyFilter extends OncePerRequestFilter {

    @Autowired(required = false)
    DispatcherServlet dispatcherServlet;

    @SneakyThrows
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 获取handler
        HandlerExecutionChain handlerExecutionChain = getHandlerFromDispatcherServlet(request);
        Object handler = handlerExecutionChain.getHandler();
        try {
            HandlerMethod hm = (HandlerMethod) handler;
            CheckWord checkWord = hm.getMethodAnnotation(CheckWord.class);
            if (checkWord == null) {
                //如果目标方法没有@CheckWord说明该接口不需要进行敏感词校验
                filterChain.doFilter(request, response);
            } else {
                request = new RequestWrapper(request);
                filterChain.doFilter(request, response);
            }
        } catch (ClassCastException e) {
            filterChain.doFilter(request, response);
        }
    }

    private HandlerExecutionChain getHandlerFromDispatcherServlet(HttpServletRequest request) throws Exception {
        List<HandlerMapping> handlerMappings = dispatcherServlet.getHandlerMappings();
        if (handlerMappings != null) {
            for (HandlerMapping mapping : handlerMappings) {
                HandlerExecutionChain handler = mapping.getHandler(request);
                if (handler != null) {
                    return handler;
                }
            }
        }
        return null;
    }
}

